//
//  BluetoothClass.m
//  BlueToothTest
//
//  Created by apple on 15/10/10.
//  Copyright © 2015年 SherrySorftware. All rights reserved.
//

#import "BluetoothClass.h"
BluetoothClass * _bluetooth = nil;
@implementation BluetoothClass


+(BluetoothClass*)shareAppDelegate {
    @synchronized(self) {
        if (_bluetooth == nil) {
            _bluetooth = [[self alloc]init];
            [[BluetoothClass shareAppDelegate] initBluetoothManager];
        }
    }
    return _bluetooth;
}
@synthesize manager;

- (void)initBluetoothManager {
    /*
     设置主设备的委托,CBCentralManagerDelegate
     必须实现的：
     - (void)centralManagerDidUpdateState:(CBCentralManager *)central;//主设备状态改变的委托，在初始化CBCentralManager的适合会打开设备，只有当设备正确打开后才能使用
     其他选择实现的委托中比较重要的：
     - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI; //找到外设的委托
     - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;//连接外设成功的委托
     - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//外设连接失败的委托
     - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//断开外设的委托
     */
    //初始化并设置委托和线程队列，最好一个线程的参数可以为nil，默认会就main线程
    manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];
    _didDiscoverPeripheral = [[NSMutableArray alloc]init];
    _peripheralInfos       = [[NSMutableArray alloc]init];
    _arr_characteristic    = [[NSMutableArray alloc]init];
}

- (NSArray*)findDidConnectDivice:(NSArray *)cbuuidArr {
    //retrieveConnectedPeripheralsWithServices:
  //return [manager retrieveConnectedPeripheralsWithServices:cbuuidArr];
    return [manager retrievePeripheralsWithIdentifiers:cbuuidArr];
}

- (void)connetDevice:(CBPeripheral *)peripheral {
    NSLog(@">>>执行连接操作");
    [manager stopScan];
    if (peripheral != nil) {
        [self.delegate updataConnetionState:@"正在连接...."];
        [manager connectPeripheral:peripheral options:nil];
    }else {
        [self.delegate updataConnetionState:@"连接失败，请确保设备开启"];
    }
}


/*!
 *  @author  jiaminqi_u@126.com, 15-10-10 11:10:38
 *
 *  主设备状态改变的委托，在初始化CBCentralManager的适合会打开设备，只有当设备正确打开后才能使用
 *
 */
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
    
    switch (central.state) {
        case CBCentralManagerStateUnknown:
            NSLog(@">>>CBCentralManagerStateUnknown");
            break;
        case CBCentralManagerStateResetting:
            NSLog(@">>>CBCentralManagerStateResetting");
            break;
        case CBCentralManagerStateUnsupported:
            NSLog(@">>>CBCentralManagerStateUnsupported");
            break;
        case CBCentralManagerStateUnauthorized:
            NSLog(@">>>CBCentralManagerStateUnauthorized");
            break;
        case CBCentralManagerStatePoweredOff:
            NSLog(@">>>CBCentralManagerStatePoweredOff");
            [self.delegate updataConnetionState:@"手机蓝牙关闭，请确保设备开启"];

            break;
        case CBCentralManagerStatePoweredOn:
            NSLog(@">>>CBCentralManagerStatePoweredOn");
            [[NSNotificationCenter defaultCenter]postNotificationName:@"CBCentralManagerStatePoweredOn" object:nil];
            //[self findDiviceNearMe];
            [self.delegate updataConnetionState:@"手机蓝牙已打开，准备扫描"];
            
            break;
        default:
            break;
    }
}

- (void)findDiviceNearMe {
    //开始扫描周围的外设
    /*
     第一个参数nil就是扫描周围所有的外设，扫描到外设后会进入
     - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI;
     */
    [manager scanForPeripheralsWithServices:nil options:nil];

}

//扫描到设备会进入方法
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
    
    NSLog(@"当扫描到设备:%@",peripheral.name);
    [self.delegate updataLog:[NSString stringWithFormat:@"当扫描到设备:%@",peripheral.name]];
    //    NSLog(@"%@",str);
    NSString * rssi = [NSString stringWithFormat:@"%@",RSSI];
    NSString * UUID = [NSString stringWithFormat:@"%@", peripheral.identifier.UUIDString];
    NSString * name = [NSString stringWithFormat:@"%@",peripheral.name];
    if ([peripheral.name isEqual:[NSNull null]]) {
        name = @"没有名字";
    }
    NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:rssi,@"rssi", UUID,@"UUID",name,@"name",nil];
    
    if (_peripheralInfos.count < 1) {
        [_peripheralInfos addObject:dict];
        [self.didDiscoverPeripheral addObject:peripheral];
        //[self.delegate updataAndReload:_peripheralInfos];
    }else
    {
        BOOL has = NO;
        for(int i  = 0 ; i < _peripheralInfos.count ; i++) {
            if ([UUID isEqualToString:[NSString stringWithFormat:@"%@",_peripheralInfos[i][@"UUID"]]]) {
                has = YES;
                return;
            }
        }
        if (has == NO) {
            [self.didDiscoverPeripheral addObject:peripheral];
            [_peripheralInfos addObject:dict];
            //[self.delegate updataAndReload:_peripheralInfos];
        }
    }

    if ([peripheral.name hasPrefix:@"myP"]){
        //连接设备
        [manager connectPeripheral:peripheral options:nil];
        [manager stopScan];
    }
    
//    if ([peripheral.name hasPrefix:@"BPM"]){
//        //连接设备
//        [manager connectPeripheral:peripheral options:nil];
//        [manager stopScan];
//    }
}

/*!
 *  @author  jiaminqi_u@126.com, 15-10-10 11:10:01
 *
 *  设备连接成功后，就可以扫描设备的服务了，同样是通过委托形式，扫描到结果后会进入委托方法。但是这个委托已经不再是主设备的委托（CBCentralManagerDelegate），而是外设的委托（CBPeripheralDelegate）,这个委托包含了主设备与外设交互的许多 回调方法，包括获取services，获取characteristics，获取characteristics的值，获取characteristics的Descriptor，和Descriptor的值，写数据，读rssi，用通知的方式订阅数据等等。
 */
//连接到Peripherals-成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    //[manager stopScan];//停止扫描
    [self.delegate updataConnetionState:@"连接成功"];
    NSLog(@">>>连接到名称为（%@）的设备-成功",peripheral);
    [self.delegate updataLog:[NSString stringWithFormat:@">>>连接到名称为（%@）的设备-成功",peripheral]];
    //保存设备信息
    NSUserDefaults *def = [[NSUserDefaults alloc]init];
    [def setObject:[peripheral name] forKey:@"Pname"];
    [def setObject:[NSString stringWithFormat:@"%@",peripheral.identifier.UUIDString] forKey:@"identifier"];
    
    //连接成功后 保存选择的设备
    [BluetoothClass shareAppDelegate].selectPeripheral = peripheral;
    //设置的peripheral委托CBPeripheralDelegate
    [peripheral setDelegate:self];
    //扫描外设Services，成功后会进入方法：-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    [peripheral discoverServices:nil];
    
    UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    if (localNotification == nil) {
        return;
    }
    localNotification.timeZone = [NSTimeZone defaultTimeZone];
    localNotification.alertBody = @"连接成功";
    localNotification.alertAction = @"查看";
    localNotification.soundName = UILocalNotificationDefaultSoundName;
    NSDictionary *infoDic = [NSDictionary dictionaryWithObjectsAndKeys:@1,@"google", nil];
    localNotification.userInfo = infoDic;
    [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}

//连接到Peripherals-失败
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@">>>连接到名称为（%@）的设备-失败,原因:%@",[peripheral name],[error localizedDescription]);
    [self.delegate updataConnetionState:@"连接失败，请检查log"];
    [self.delegate updataLog:[NSString stringWithFormat:@">>>连接到名称为（%@）的设备-失败,原因:%@",[peripheral name],[error localizedDescription]]];
}

//  Peripherals断开连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    NSLog(@">>>外设连接断开连接 %@: %@\n", [peripheral name], [error localizedDescription]);
    [self.delegate updataLog:[NSString stringWithFormat:@">>>外设连接断开连接 %@: %@\n", [peripheral name], [error localizedDescription]]];
    [self.delegate updataConnetionState:@"连接断开，请检查log"];
    
    
    UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    if (localNotification == nil) {
        return;
    }
    localNotification.timeZone = [NSTimeZone defaultTimeZone];
    localNotification.alertBody = @"已断开连接";
    localNotification.alertAction = @"查看";
    localNotification.soundName = UILocalNotificationDefaultSoundName;
    NSDictionary *infoDic = [NSDictionary dictionaryWithObjectsAndKeys:@1,@"google", nil];
    localNotification.userInfo = infoDic;
    [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
    
    //尝试重新连接
    NSArray *arr = [NSArray arrayWithObject:[BluetoothClass shareAppDelegate].selectPeripheral.identifier.UUIDString];
    [manager retrievePeripheralsWithIdentifiers:arr];
}


//扫描到Services
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    NSLog(@">>>扫描到服务：%@",peripheral.services);
    if (error)
    {
        NSLog(@">>>Discovered services for %@ with error: %@", peripheral.name, [error localizedDescription]);
        [self.delegate updataLog:[NSString stringWithFormat:@">>>Discovered services for %@ with error: %@", peripheral.name, [error localizedDescription]]];
        return;
    }
    
    for (CBService *service in peripheral.services) {
        //NSLog(@"%@",service.UUID);
        //扫描每个service的Characteristics，扫描到后会进入方法： -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
        [peripheral discoverCharacteristics:nil forService:service];
    }
    
}

//扫描到Characteristics
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    if (error)
    {
        NSLog(@"error Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]);
        [self.delegate updataLog:[NSString stringWithFormat:@"error Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]]];
        return;
    }
    
//    for (CBCharacteristic *characteristic in service.characteristics)
//    {
//        //NSLog(@"service:%@ 的 Characteristic: %@",service.UUID,characteristic.UUID);
//    }
    
    //获取Characteristic的值，读到数据会进入方法：-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
    //    for (CBCharacteristic *characteristic in service.characteristics){
    //        {
    //            //获得数据
    //            [peripheral readValueForCharacteristic:characteristic];
    //        }
    //    }
    
    //搜索Characteristic的Descriptors，读到数据会进入方法：-(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
    for (CBCharacteristic *characteristic in service.characteristics){
        [peripheral discoverDescriptorsForCharacteristic:characteristic];
    }
    
    for (CBCharacteristic * characteristic in service.characteristics)
    {
        //设置通知，数据通知会进入：didUpdateValueForCharacteristic方法
        [peripheral setNotifyValue:YES forCharacteristic:characteristic];
    }
}


//获取的charateristic的值
-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    
    //传到controller
    
    //判断是哪一个设备
    if ([characteristic.service.peripheral.name hasPrefix:@"BJYC"]) {//北京怡成 血糖仪
        NSString * dataString = [self hexStringFromHexData:characteristic.value];
        [self.delegate didGetNewData:dataString];
    }
    if ([characteristic.service.peripheral.name hasPrefix:@"MTK"]) {//实捷血压计
        NSString * dataString = [self hexStringFromHexData:characteristic.value];
        [self.delegate didGetNewData:dataString];
    }
    if ([peripheral.identifier.UUIDString hasPrefix:self.selectPeripheral.identifier.UUIDString]) {
        NSString *str = [[NSString alloc]initWithData:characteristic.value encoding:NSUTF8StringEncoding];
        [self.delegate didGetNewData:str];
        [self.delegate updataLog:[NSString stringWithFormat:@"%@",str]];
    }
}

//搜索到Characteristic的Descriptors
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    //打印出Characteristic和他的Descriptors
    NSLog(@"characteristic uuid:%@",characteristic.UUID);
    [self.delegate updataLog:[NSString stringWithFormat:@"characteristic uuid:%@",characteristic.UUID]];
    [self.arr_characteristic addObject:characteristic];
    for (CBDescriptor *d in characteristic.descriptors) {
        NSLog(@"Descriptor uuid:%@",d.UUID);
    }
}

//获取到Descriptors的值
-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error{
    //打印出DescriptorsUUID 和value
    //这个descriptor都是对于characteristic的描述，一般都是字符串，所以这里我们转换成字符串去解析
    NSLog(@"characteristic uuid:%@  value:%@",[NSString stringWithFormat:@"%@",descriptor.UUID],descriptor.value);
    [self.delegate updataLog:[NSString stringWithFormat:@"characteristic uuid:%@  value:%@",[NSString stringWithFormat:@"%@",descriptor.UUID],descriptor.value]];
}

- (void)writeDateWithData:(NSData*)data {
    
    //    for (int i = 0 ; i < self.arr_characteristic.count; i++) {
    //        [self writeCharacteristic:self.selectPeripheral characteristic:self.arr_characteristic[self.arr_characteristic.count - 1] value:data];
    //    }
    if (self.arr_characteristic.count > 0) {
        [self writeCharacteristic:self.selectPeripheral characteristic:self.arr_characteristic[self.arr_characteristic.count - 1] value:data];
    }else {
        UIAlertView * alter =[ [UIAlertView alloc]initWithTitle:@"错误" message:@"未连接设备" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确认", nil];
        [alter show];
    }
    

   // NSLog(@"write date = 【%@】",data);
}

//写数据
-(void)writeCharacteristic:(CBPeripheral *)peripheral
            characteristic:(CBCharacteristic *)characteristic
                     value:(NSData *)value{
    
    //打印出 characteristic 的权限，可以看到有很多种，这是一个NS_OPTIONS，就是可以同时用于好几个值，常见的有read，write，notify，indicate，知道这几个基本就够用了，前连个是读写权限，后两个都是通知，两种不同的通知方式。
 
    NSLog(@"\n\n\n\n\n");
     NSLog(@"%lu",(unsigned long)characteristic.properties);
    NSLog(@"%@",characteristic);
    //NSLog(@"%@",peripheral);
    NSLog(@"\n\n");
    
    //只有 characteristic.properties 有write的权限才可以写
    if(characteristic.properties & CBCharacteristicPropertyWrite){
        /*
         最好一个type参数可以为CBCharacteristicWriteWithResponse或type:CBCharacteristicWriteWithResponse,区别是是否会有反馈
         */
        [peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
        
    }else{
        NSLog(@"该字段不可写！");
    }

}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
    if (error) {
        NSLog(@"写入错误:%@",[error localizedDescription]);
    }else {
        NSLog(@"写入成功");
    }
}

- (NSString*)hexStringFromHexData:(NSData *)aData {
    const unsigned char* dataBuffer = (const unsigned char*)[aData bytes];
    if (!dataBuffer) {
        return nil;
    }
    NSUInteger dataLength = [aData length];
    NSMutableString* hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
    for (int i = 0; i < dataLength; i++) {
        [hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
    }
    return [hexString uppercaseString];
}

+ (NSString*)interChangeValue:(NSString*)string{
    NSString * str =  [NSString stringWithFormat:@"%lu",strtoul([string UTF8String],0,16)];
    return str;
}
@end
